package imdbfolder.app;

import imdbfolder.gui.ImdbFolderController;
import imdbfolder.workers.MyWorker;

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

import org.jvnet.substance.skin.SubstanceRavenGraphiteGlassLookAndFeel;

public class Application {

    public static final String VERSION = "0.4.1";

    private static ExecutorService threadPool;

    private static ExecutorService priorityThreadPool;

    private static ImdbFolderController controller;

    public static void main(String[] args) {
        setLookAndFeel();
        initializeThreadpools();

        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                controller = new ImdbFolderController();
                controller.initalize();
            }

        });
    }

    private static void initializeThreadpools() {
        threadPool = Executors.newFixedThreadPool(1);
        priorityThreadPool = Executors.newFixedThreadPool(1);
    }

    private static void setLookAndFeel() {
        try {
            UIManager.setLookAndFeel(new SubstanceRavenGraphiteGlassLookAndFeel());
        }
        catch (UnsupportedLookAndFeelException e) {
            e.printStackTrace();
        }
    }

    private static List<MyWorker<?, ?>> workers = new ArrayList<MyWorker<?, ?>>();

    public static void runTask(final MyWorker<?, ?> worker, boolean highPriority) {
        if (highPriority) {
            priorityThreadPool.submit(worker);
        }
        else {
            threadPool.submit(worker);
        }

        workers.add(worker);

        worker.addstartedListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                controller.registerWorker(worker);
            }
        });

        worker.addFinishedListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                removeWorker(worker);
            }

        });
    }

    public static void cancelWorkers() {
        threadPool.shutdownNow();
        priorityThreadPool.shutdownNow();

        for (MyWorker<?, ?> worker : workers) {
            worker.cancel(true);
        }

        workers.clear();

        initializeThreadpools();
    }

    private static void removeWorker(MyWorker<?, ?> worker) {
        controller.deregisterWorker(worker);

        workers.remove(worker);

        worker = null;
    }
}